/**
 * 统一封装异步请求：
 * 移动端H5前店在未来也包括个人中心的一部分，因此有可能连接报表服务器，并使用数据导出下载功能
 */
//import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import { showConfirmDialog, showFailToast } from 'vant';
//todo: 前期示例，先别管权限及其拦截器，后期再做
//import useStore from '@/store'
import axios from 'axios'
import { localStorage } from '@/utils/storage'
import _ from "lodash"
class AjaxRequest {

    private request(contextPath:string,reqUrl:string,reqData={}, reqType = 'json',showError=true) {
        const tokenKey = import.meta.env.VITE_TOKEN_KEY
        //兼容问题
        if(_.isEmpty(Promise.prototype.finally)) {
            Promise.prototype.finally = function (callback) {
                let Promise = this.constructor
                return this.then(
                    (value)=> {
                        // @ts-ignore
                        Promise.resolve(callback()).then(
                            ()=>{ return value }
                        )
                    },
                    (reason)=> {
                        // @ts-ignore
                        Promise.resolve(callback()).then(
                            ()=> { throw reason }
                        )
                    }
                )
            }
        }
        return new Promise((resolve, reject)=>{
            if('http:' == document.location.protocol){   //http协议
                contextPath = contextPath.replace(/^https/,"http")
            }
            //请求头部、请求参数
            let headers:any = {}, params:any
            if (reqType == "json" || reqType == "export") {
                headers["Content-Type"] = "application/json;charset=UTF-8";
                params = JSON.stringify(reqData);
            } else {
                headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
                params = new URLSearchParams();
                if (reqData !== null && typeof reqData === 'object' ) {
                    _.forEach(reqData, function (val:any, key:string) {
                        params.append(key, val);
                    });
                }
            }
            //本地开发时，模拟生产环境放一些固定信息到header中，与后台管理中心不同，前店userInfo内容较少，不需要庞大的权限树
            //WEG_USER_SESSION_ID
            //WEG_USER_INFO_HEAD
            // if (!isProduction) {
            //     const store = userStore();
            //     headers["WEG_USER_INFO_HEAD"] = encodeURIComponent(JSON.stringify(store.staffVo));
            //     headers["WEG_USER_SESSION_ID"] = encodeURIComponent("B36F940624964DC0BD62B2DD2508329B");
            // }

            // 将可能的token放到请求header中，以适应微信小程序、微信浏览器等前端环境
            let accessToken = localStorage.get(tokenKey)
            if(!_.isEmpty(accessToken) && accessToken !== 'null'){
                headers[tokenKey] = accessToken
            }

            axios({
                method: 'post',
                url: contextPath + reqUrl,
                data:params,
                headers:headers,
                responseType: reqType == "export"? 'blob':undefined,
            }).then( (response)=> {
                // 将可能的token放从响应header中获取，以适应微信小程序、微信浏览器等前端环境
                if(!_.isEmpty(response.headers[tokenKey])){
                    localStorage.set(tokenKey,response.headers[tokenKey])
                }
                if(reqType == "export"){ //对导出文件的处理
                    const url = window.URL.createObjectURL(new Blob([response.data]))
                    const link = document.createElement("a")
                    link.href = url
                    //解析文件名
                    let filename = response.headers["file-download-name"] as string
                    link.download = decodeURI(filename);
                    document.body.appendChild(link)
                    link.click()
                    document.body.removeChild(link) //下载完成移除元素
                    window.URL.revokeObjectURL(url) //释放掉blob对象

                    resolve(filename)
                }else{
                    const {success,code=null,msg=null} =response.data
                    if(false===success){
                        if (showError) {
                            showFailToast(code || msg ? code + ": " + msg : '系统出错')
                        }
                        reject({
                            response: {code:code, msg:msg}
                        })
                    } else {
                        if (response.data instanceof ArrayBuffer) { //如果是响应数据为二进制流处理(Excel导出)，则不可以输入日志
                            resolve(response)
                        }else{
                            //console.log('response', response)
                            resolve(response.data)
                        }
                    }
                }

            }).catch( (error)=> {
                let status=200
                let showMsg = ""
                // 【务必注意】这里的error输出的不是一个对象【error.response才是一个对象】
                if (error.response) {
                    status = error.response.status
                    console.log(status+' error.response.data',error.response.data)
                    console.log(status+' error.response.status',error.response.status)
                    console.log(status+' error.response.headers',error.response.headers)
                    // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围

                } else if (error.request) {
                    // 请求已经成功发起，但没有收到响应
                    console.log('502 error.request',error.request)
                    status = 502
                } else {
                    // 发送请求时出了点问题
                    console.log('501 error.message', error.message)
                    status = 501
                }
                console.log('error.config',error.config)


                if(401 == status){
                    showMsg = "401 未登陆"
                } else if(403 == status){
                    showMsg = "403 您没有访问权限"
                } else if(404 == status){
                    showMsg = "404 请求不存在"
                } else if(400 == status){
                    showMsg = "400服务器无法解析参数"
                } else if(500 == status){
                    showMsg = "500 服务器异常"
                } else if(502 == status){
                    showMsg = "502 服务不可用"
                } else if(504 == status){
                    showMsg = "504 服务器响应超时"
                } else{
                    showMsg = "无效的请求: "+error.message
                }

                if(401 !== status) {
                    if (showError) {
                        showFailToast(reqUrl + " : " + showMsg)
                    }
                    reject(error)
                }else{
                    showConfirmDialog( {
                        title: '提示',
                        message: '当前页面已失效，请重新登录',
                    }).then(() => {
                        localStorage.clear()
                        window.location.href = '/login/'  //todo: 这里要改成前往指定的登录页
                    });
                    reject({ //这句一般用来在路由beforeEach时抛出一个异常
                        response:{code:status,msg:showMsg}
                    })
                }
            })
        })
    }
    public wegSv(reqUrl:string, reqData = {}, reqType = 'json', showError = true){
        return this.request(import.meta.env.VITE_WEG_URL, reqUrl, reqData, reqType, showError);
    }
    public reportSv(reqUrl:string, reqData = {}, reqType = 'json', showError = true){
        return this.request(import.meta.env.VITE_REPORT_URL, reqUrl, reqData, reqType, showError);
    }
    public baseSv(reqUrl:string, reqData = {}, reqType = 'json', showError = true){
        return this.request(import.meta.env.VITE_BASE_URL, reqUrl, reqData, reqType, showError);
    }
}
const Ajax = new AjaxRequest();
export default Ajax